﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using SmartSiteManagementSystem.IServices;
using SmartSiteManagementSystem.Models.Admin;
using SmartSiteManagementSystem.Utils;
using SmartSiteManagementSystem.AdminWeb.Extensions;
using SmartSiteManagementSystem.AdminWeb.Common;

namespace SmartSiteManagementSystem.AdminWeb.Filter
{
    public class LoginAuthorizeAttribute : IAuthorizationFilter
    {
        private readonly ILogger<LoginAuthorizeAttribute> _logger;
        private readonly IAdminService _adminService;
        private readonly IHttpContextAccessor _contextAccessor;
        public LoginAuthorizeAttribute(IAdminService adminService, IHttpContextAccessor contextAccessor,ILogger<LoginAuthorizeAttribute> logger)
        {
            _logger = logger;
            _adminService = adminService;
            _contextAccessor = contextAccessor;
        }

        /// <summary>
        /// 获取cookies
        /// </summary>
        /// <param name="key">键</param>
        /// <returns>返回对应的值</returns>
        private string GetCookies(string key)
        {
            _contextAccessor.HttpContext.Request.Cookies.TryGetValue(key, out string value);
            if (string.IsNullOrEmpty(value))
            {
                value = string.Empty;
            }
            return value;
        }



        public void OnAuthorization(AuthorizationFilterContext context)
        {
            if (context.Filters.Any(it => it is Microsoft.AspNetCore.Mvc.Authorization.IAllowAnonymousFilter))
            {
                #region 不需要登录操作不操作放行
                #endregion
            }
            else
            {
                #region //验证cookie签名 验证客户端

                ActionResult result = new RedirectResult("/Login/Index");
                string clientIP = IPUtils.GetIPRealAddress(_contextAccessor.HttpContext);
                try
                {
                    string encryCookieVal = GetCookies(SessionCookieKeyHelper.CookiesUserIdKey);
                    string cookieVal = "";
                    if (!string.IsNullOrEmpty(encryCookieVal))
                    {
                        cookieVal = new DESSecurity().DesDecrypt(encryCookieVal);
                    }

                   
                    string sign = GetCookies(SessionCookieKeyHelper.CookiesKey);
                    if (string.IsNullOrEmpty(cookieVal) || string.IsNullOrEmpty(sign))
                    {
                        _contextAccessor.HttpContext.Session.Remove(SessionCookieKeyHelper.SessionKey);
                        _contextAccessor.HttpContext.Response.Cookies.Delete(SessionCookieKeyHelper.CookiesKey);
                        _contextAccessor.HttpContext.Response.Cookies.Delete(SessionCookieKeyHelper.CookiesUserIdKey);
                        context.Result = result;
                    }
                    else
                    {


                        int AdminUserId = Convert.ToInt32(cookieVal);

                        AdminUserInfo AdminUserObj = _adminService.GetAdminUserInfoByUserId(AdminUserId);
                        string sign_v = UserUtil.GenFlagString(AdminUserObj.UserName, AdminUserObj.UserPwd, AdminUserObj.AdminUserId, clientIP);
                        if (sign != sign_v)  //签名验证失败
                        {
                          
                            _contextAccessor.HttpContext.Session.Remove(SessionCookieKeyHelper.SessionKey);
                            _contextAccessor.HttpContext.Response.Cookies.Delete(SessionCookieKeyHelper.CookiesUserIdKey);
                            _contextAccessor.HttpContext.Response.Cookies.Delete(SessionCookieKeyHelper.CookiesKey);
                            context.Result = result;
                        }
                        else
                        {
                            _contextAccessor.HttpContext.Session.Set<AdminUserInfo>(SessionCookieKeyHelper.SessionKey, AdminUserObj);
                            return;
                        }
                    }
                }
                catch (Exception ex)
                {
                    context.Result = result;
                    _logger.LogError("验证管理员登录cookie出错", ex);
                }
                #endregion
            }
        }
    }
}
